﻿using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Text;
using System.Reflection;
using ExpenseSystem.Common.BaseModel;

namespace ExpenseSystem.Common
{
    public static class JsonHelper
    {
        public static T FromJson<T>(string json)
        {
            T jsonObj = JsonConvert.DeserializeObject<T>(json);
            return jsonObj;
        }
        public static string ArrayToJsonForExport<T>(IList<T> list) where T : EModel
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("[");
            foreach (T obj in list)
            {
                stringBuilder.Append(ToJsonForExport(obj));
                stringBuilder.Append(",");
            }
            if (stringBuilder[stringBuilder.Length - 1] == ',')
                stringBuilder.Remove(stringBuilder.Length - 1, 1);
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }
        public static string ToJsonForExport<T>(T obj) where T : EModel
        {
            PropertyInfo[] propertys = obj.GetType().GetProperties();
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PropertyInfo prop in propertys)
            {
                ExportAttribute exportAttribute = prop.GetCustomAttribute<ExportAttribute>(false);
                if (exportAttribute!=null)
                {
                    object val = prop.GetValue(obj);
                    if (val == null)
                        stringBuilder.AppendFormat("\"{0}\":null,", exportAttribute.HeaderName);
                    else
                    {
                        Type valType = val.GetType();
                        if (valType == typeof(Int32)
                            || valType == typeof(Int16)
                            || valType == typeof(Int64)
                            || valType == typeof(Single)
                            || valType == typeof(Double)
                            || valType == typeof(Decimal))
                            stringBuilder.AppendFormat("\"{0}\":{1},", exportAttribute.HeaderName, val);
                        else if (valType == typeof(Boolean))
                            stringBuilder.AppendFormat("\"{0}\":{1},", exportAttribute.HeaderName, val.ToString().ToLower());
                        else
                            stringBuilder.AppendFormat("\"{0}\":\"{1}\",", exportAttribute.HeaderName, val);
                    }
                }
            }
            if (stringBuilder.Length > 0)
                stringBuilder.Remove(stringBuilder.Length - 1, 1);
            return "{" + stringBuilder.ToString() + "}";
        }
        public static string ArrayToJson<T>(IList<T> list,Inhibition inhibition) where T : EModel
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("[");
            foreach(T obj in list)
            {
                stringBuilder.Append(ToJson(obj,inhibition));
                stringBuilder.Append(",");
            }
            if (stringBuilder[stringBuilder.Length - 1] == ',')
                stringBuilder.Remove(stringBuilder.Length - 1, 1);
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }
        public static string ToJson<T>(T obj,Inhibition inhibition)where T:EModel
        {
            PropertyInfo[] propertys = obj.GetType().GetProperties();
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PropertyInfo prop in propertys)
            {
                if (inhibition == null || inhibition.Fields == null || !inhibition.Fields.Contains(prop.Name))
                {
                    object val = prop.GetValue(obj);
                    if (val == null)
                        stringBuilder.AppendFormat("\"{0}\":null,", prop.Name);
                    else
                    {
                        Type valType = val.GetType();
                        if (valType == typeof(Int32)
                            || valType == typeof(Int16)
                            || valType == typeof(Int64)
                            || valType == typeof(Single)
                            || valType == typeof(Double)
                            || valType == typeof(Decimal))
                            stringBuilder.AppendFormat("\"{0}\":{1},", prop.Name, val);
                        else if (valType == typeof(Boolean))
                            stringBuilder.AppendFormat("\"{0}\":{1},", prop.Name, val.ToString().ToLower());
                        else
                            stringBuilder.AppendFormat("\"{0}\":\"{1}\",", prop.Name, val);
                    }
                }
            }
            if (stringBuilder.Length > 0)
                stringBuilder.Remove(stringBuilder.Length - 1, 1);
            return "{"+ stringBuilder.ToString()+"}";
        }
    }
}
